package nl.depository.pim.security;

import java.io.IOException;

import nl.depository.pim.annotations.AnonymousAccess;
import nl.depository.pim.services.Authenticator;

import org.apache.tapestry5.Link;
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.services.ComponentEventRequestParameters;
import org.apache.tapestry5.services.ComponentRequestFilter;
import org.apache.tapestry5.services.ComponentRequestHandler;
import org.apache.tapestry5.services.ComponentSource;
import org.apache.tapestry5.services.PageRenderLinkSource;
import org.apache.tapestry5.services.PageRenderRequestParameters;
import org.apache.tapestry5.services.Response;

public class AuthenticationFilter implements ComponentRequestFilter
{
	final private PageRenderLinkSource pageRenderLinkSource;
	
	final private ComponentSource componentSource;
	
	final private Response response;
	
	final private Authenticator authenticator;
	
	final String defaultPageName = "Dashboard";
	
	final String loginPageName = "Login";
	
	final String logoutPageName = "Logout";
	
	public AuthenticationFilter(PageRenderLinkSource pageRenderLinkSource, ComponentSource componentSource, Response response, Authenticator authenticator)
	{
		this.pageRenderLinkSource = pageRenderLinkSource;
		this.componentSource = componentSource;
		this.response = response;
		this.authenticator = authenticator;
	}
	
	public void handleComponentEvent(ComponentEventRequestParameters parameters, ComponentRequestHandler handler) throws IOException
	{
		if (!dispatchedToLoginPage(parameters.getActivePageName()))
		{
			handler.handleComponentEvent(parameters);
		}
	}
	
	public void handlePageRender(PageRenderRequestParameters parameters, ComponentRequestHandler handler) throws IOException
	{
		if (!dispatchedToLoginPage(parameters.getLogicalPageName()))
		{
			handler.handlePageRender(parameters);
		}
	}
	
	private boolean dispatchedToLoginPage(String pageName) throws IOException
	{
		if (authenticator.isLoggedIn())
		{
			if (loginPageName.equalsIgnoreCase(pageName))
			{
				Link link = pageRenderLinkSource.createPageRenderLink(defaultPageName);
				response.sendRedirect(link);
				return true;
			}
			
			return false;
		}
		
		Component page = componentSource.getPage(pageName);
		if (page.getClass().isAnnotationPresent(AnonymousAccess.class))
		{
			return false;
		}
		
		Link link = pageRenderLinkSource.createPageRenderLink(loginPageName);
		response.sendRedirect(link);
		return true;
	}
}
